package springx.uitils;

import io.minio.MinioClient;
import io.minio.ObjectStat;
import io.minio.PutObjectOptions;
import io.minio.messages.Bucket;
import io.swagger.models.auth.In;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import springx.config.MinioConfig;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;

/**
 * minio工具类
 */
@Slf4j
@Component
public class MinioUtil {
    @Autowired
    MinioConfig minIoProperties;

    private static MinioClient minioClient;

    /**
     * 初始化minio的配置
     * 2022年5月11日16:04:59 夏金辰
     */
    @PostConstruct
    public void  init(){
        try {
            minioClient = new MinioClient(minIoProperties.getUrl(), minIoProperties.getAccessKey(),
                    minIoProperties.getSecretKey());
            createBucket(minIoProperties.getBucketName());
        }catch (Exception e){
            e.printStackTrace();
            log.error("初始化minio配置异常：",e.fillInStackTrace());
        }
    }

    /**
     * 判断桶子是否存在
     * @param bucketName
     * @return
     */
    @SneakyThrows(Exception.class)
    public static boolean bucketExists(String bucketName){
        return minioClient.bucketExists(bucketName);
    }

    /**
     * 如果桶子不存在的话就创建一个桶子
     * @param bucketName
     */
    @SneakyThrows(Exception.class)
    public void createBucket(String bucketName) {
        boolean isExist = minioClient.bucketExists(bucketName);
        if (!isExist){
            minioClient.makeBucket(bucketName);
        }
    }

    /**
     * 获取所有桶子
     * @return
     */
    @SneakyThrows(Exception.class)
    public static List<Bucket> getAllBucket(){
        return minioClient.listBuckets();
    }

    /**
     * 文件上传
     * @param bucketName 桶子名称
     * @param fileName 文件名
     * @param filePath 路径
     * @return
     */
    @SneakyThrows(Exception.class)
    public  static String upload(String bucketName,String fileName,String filePath){
        minioClient.putObject(bucketName,fileName,filePath,null);
        return getFileUrl(bucketName,fileName);
    }

    /**
     * 文件上传
     * @param bucketName 桶子名称
     * @param fileName 文件名
     * @param stream 输入流
     * @return
     */
    @SneakyThrows(Exception.class)
    public  static String upload(String bucketName, String fileName, InputStream stream){
        minioClient.putObject(bucketName,fileName,stream,new PutObjectOptions(stream.available(),-1));
        return getFileUrl(bucketName,fileName);
    }


    /**
     * 文件上传
     * @param bucketName 上传的桶子名称
     * @param file 文件名字
     * @return
     */
    @SneakyThrows(Exception.class)
    public  static String upload(String bucketName, MultipartFile file){
        final InputStream inputStream = file.getInputStream();
        final String fileName = file.getOriginalFilename();
        minioClient.putObject(bucketName,fileName,inputStream, new PutObjectOptions(inputStream.available(),-1));
        inputStream.close();
        return getFileUrl(bucketName,fileName);
    }
    /**
     * 文件删除
     * @param bucketName 桶子名称
     * @param fileName 文件名
     * @return
     */
    @SneakyThrows(Exception.class)
    public  static void deleteFile(String bucketName, String fileName){
        minioClient.removeObject(bucketName,fileName);
    }

    /**
     * 文件下载
     * @param bucketName
     * @param fileName
     * @param response
     */
    @SneakyThrows(Exception.class)
    public static  void  download(String bucketName, String fileName, HttpServletResponse response){
        //获取对象的元数据
        final ObjectStat stat = minioClient.statObject(bucketName,fileName);
        response.setContentType(stat.contentType());
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        InputStream inputStream = minioClient.getObject(bucketName,fileName);
        IOUtils.copy(inputStream,response.getOutputStream());
        inputStream.close();
    }


    /**
     * 获取minio下载地址
     * @param bucketName
     * @param fileName
     * @return
     */
    @SneakyThrows(Exception.class)
    public static String getFileUrl(String bucketName, String fileName) {
        return minioClient.presignedGetObject(bucketName,fileName);
    }
}
